#include "Wt.h"

void WtInitOptionKeys(WtContext *w)
{
  Tcl_HashEntry *ent;
  int created;

  if (w->optionCodes) {
    return;
  }

  w->optionCodes = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.reuseInterp", &created);
  Tcl_SetHashValue(ent, WT_SERVER_REUSE_INTERP);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.deleteInterp", &created);
  Tcl_SetHashValue(ent, WT_SERVER_DELETE_INTERP);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.wtPackage", &created);
  Tcl_SetHashValue(ent, WT_SERVER_WT_PACKAGE);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.interpCreateScript", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INTERP_CREATE_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.interpDestroyScript", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INTERP_DESTROY_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.includeStartScript", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INCLUDE_START_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.includeEndScript", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INCLUDE_END_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.includeNamespace", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INCLUDE_NAMESPACE);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.addHeaderTrailer", &created);
  Tcl_SetHashValue(ent, WT_SERVER_ADD_HEADER_TRAILER);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.includeHeader", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INCLUDE_HEADER);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.includeTrailer", &created);
  Tcl_SetHashValue(ent, WT_SERVER_INCLUDE_TRAILER);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.scriptStartString", &created);
  Tcl_SetHashValue(ent, WT_SERVER_SCRIPT_START_STRING);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.scriptEndString", &created);
  Tcl_SetHashValue(ent, WT_SERVER_SCRIPT_END_STRING);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.evalText", &created);
  Tcl_SetHashValue(ent, WT_SERVER_EVAL_TEXT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "server.errorHandler", &created);
  Tcl_SetHashValue(ent, WT_SERVER_ERROR_HANDLER);

  ent = Tcl_CreateHashEntry(w->optionCodes, "request.startScript", &created);
  Tcl_SetHashValue(ent, WT_REQUEST_START_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "request.endScript", &created);
  Tcl_SetHashValue(ent, WT_REQUEST_END_SCRIPT);

  ent = Tcl_CreateHashEntry(w->optionCodes, "session.cookieName", &created);
  Tcl_SetHashValue(ent, WT_SESSION_COOKIE_NAME);

  ent = Tcl_CreateHashEntry(w->optionCodes, "session.maxIdleTime", &created);
  Tcl_SetHashValue(ent, WT_SESSION_MAX_IDLE_TIME);

  ent = Tcl_CreateHashEntry(w->optionCodes, "session.sweepProbability", &created);
  Tcl_SetHashValue(ent, WT_SESSION_SWEEP_PROBABILITY);
}

WtOptionCode WtGetOptionCode(const char *key, WtContext *w)
{
  Tcl_HashEntry *ent;

  WtInitOptionCodes();

  if (ent = Tcl_FindHashEntry(w->optionCodes, key)) {
    return (WtOptionCode)Tcl_GetHashValue(ent);
  }

  return WT_UNKNOWN_OPTION;
}

/* Initialize basic request settings. Called once per
   request after the interp is setup. */

int InitRequestSettings(WtContext *w, Tcl_Obj *settings, Tcl_Interp *interp)
{
  Tcl_HashTable *settingsTable = WtGetTableMap(settings);
  TcL_HashEntry *ent;
  Tcl_HashSearch search;
  const char *key;
  Tcl_Obj *list, *val;

  ent = Tcl_FirstHashEntry(settingsTable, &search);
  while (ent) {
    key = WtToString((Tcl_Obj *)Tcl_GetHashKey(settingsTable, ent));
    list = (Tcl_Obj *)Tcl_GetHashValue(ent);
    val = list ? WtGetFirstListElement(list) : NULL;
    WtInitSetting(w, key, val, interp);
    ent = Tcl_NextHashEntry(&search);
  }
}

/* Initialize the given basic setting */

int WtInitPageSetting(WtContext *w, const char *key, Tcl_Obj *val, Tcl_Interp *interp)
{
  int opt, flag, ok = 0;

  opt = WtGetOptionCode(key);

  switch (opt) {

    case WT_SERVER_WT_PACKAGE:
      w->active->server.wtPackage = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_INTERP_CREATE_SCRIPT:
      w->active->server.interpCreateScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_INTERP_DESTROY_SCRIPT:
      w->active->server.interpDestroyScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_INCLUDE_START_SCRIPT:
      w->active->server.includeStartScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_INCLUDE_END_SCRIPT:
      w->active->server.includeEndScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_INCLUDE_NAMESPACE:
      w->active->server.includeNamespace = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_ADD_HEADER_TRAILER:
      if (Tcl_GetBooleanFromObj(interp, val, &flag) != TCL_OK) {
        ok = 0;
      } else {
        w->active->server.addHeaderTrailer = flag;
      }
      break;

    case WT_INCLUDE_HEADER:
      w->active->server.includeHeader = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_INCLUDE_TRAILER:
      w->active->server.includeTrailer = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SCRIPT_START_STRING:
      w->active->server.scriptStartString = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SCRIPT_END_STRING:
      w->active->server.scriptEndString = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SERVER_EVAL_TEXT:
      if (Tcl_GetBooleanFromObj(interp, val, &flag) != TCL_OK) {
        ok = 0;
      } else {
        w->active->server.evalText = flag;
      }
      break;

    case WT_SERVER_ERROR_HANDLER:
      w->active->server.errorHandler = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_REQUEST_START_SCRIPT:
      w->active->request.startScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_REQUEST_END_SCRIPT:
      w->active->request.endScript = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SESSION_COOKIE_NAME:
      w->active->session.cookieName = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_SESSION_MAX_IDLE_TIME:
      if (Tcl_GetIntFromObj(interp, val, &intVal) != TCL_OK) {
        ok = 0;
      } else {
        w->active->session.maxIdleTime = intVal;
      }

    case WT_SESSION_SWEEP_PROBABILITY:
      if (Tcl_GetDoubleFromObj(interp, val, &dblVal) != TCL_OK) {
        ok = 0;
      } else {
        w->active->session.sweepProbability = intVal;
      }
      w->active->server. = val;
      Tcl_GetDoubleIncrRefCount(val);
      break;

    case WT_:
      w->active->server. = val;
      Tcl_IncrRefCount(val);
      break;

    case WT_:
      w->active->server. = val;
      Tcl_IncrRefCount(val);
      break;
  }

  val = WtTableGetObjFromStr(settings, "server.interpCreateScript", NULL);
  if (val) {

  }

  val = WtTableGetObjFromStr(settings, "server.interpDestroyScript", NULL);
  if (val) {
    w->active->server.destroyScript = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.includeStartScript", NULL);
  if (val) {
    w->active->server.includeStartScript = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.includeEndScript", NULL);
  if (val) {
    w->active->server.includeEndScript = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.includeNamespace", NULL);
  if (val) {
    w->active->server.includeNamespace = val;
    Tcl_IncrRefCount(val);
  }

  flag = WtTableGetBoolFromStr(settings, "server.addHeaderTrailer", -1);
  if (flag != -1) {
    w->active->server.addHeaderTrailer = flag;
  }

  val = WtTableGetObjFromStr(settings, "server.includeHeader", NULL);
  if (val) {
    w->active->server.includeHeader = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.includeTrailer", NULL);
  if (val) {
    w->active->server.includeTrailer = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.scriptStartString", NULL);
  if (val) {
    w->active->server.scriptStartString = val;
    Tcl_IncrRefCount(val);
  }

  val = WtTableGetObjFromStr(settings, "server.scriptEndString", NULL);
  if (val) {
    w->active->server.scriptEndString = val;
    Tcl_IncrRefCount(val);
  }
}
